package com.xingfly.web.api;

import com.xingfly.authentication.annotation.Authorization;
import com.xingfly.constant.ErrorConstant;
import com.xingfly.constant.RoleConstant;
import com.xingfly.constant.HttpStatus;
import com.xingfly.error.TipException;
import com.xingfly.model.Event;
import com.xingfly.model.Role;
import com.xingfly.model.User;
import com.xingfly.model.dto.AuthorizationDTO;
import com.xingfly.model.vo.FeedVO;
import com.xingfly.model.vo.UserVO;
import com.xingfly.service.*;
import com.xingfly.util.FeedUtils;
import com.xingfly.web.model.ResponseModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by SuperS on 17/05/2017.
 *
 * @author SuperS
 */
@RestController
@RequestMapping("/api/users")
@Api(value = "users", description = "用户相关API")
public class UserController {
    //用户服务
    @Autowired
    private UserService userService;
    @Autowired
    private FeedService feedService;
    @Autowired
    private PostService postService;
    @Autowired
    private CountService countService;
    @Autowired
    private ImageService imageService;
    @Autowired
    private CommentService commentService;
    @Autowired
    private FriendService friendService;
    @Autowired
    private RoleService roleService;


    @ApiOperation(value = "获取用户列表", notes = "分页获取用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query")
    })
    @GetMapping
    public ResponseModel<?> getUsers(@RequestParam(name = "page", required = false, defaultValue = "0") Integer page,
                                     @RequestParam(name = "size", required = false, defaultValue = "10") Integer size) {
        //分页获取用户信息默认显示为10条、降序排列
        List<User> users = userService.getUsers(new PageRequest(page, size, new Sort(Sort.Direction.DESC, "id"))).getContent();
        //将User模型转换成 UserVO
        List<UserVO> userVOS = new ArrayList<>();
        for (User user : users) {
            UserVO userVO = UserVO.toVO(user);
            userVOS.add(userVO);
        }
        //统一返回格式
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(userVOS).build();
    }

    @ApiOperation(value = "创建用户", notes = "创建用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "authorizationDTO", required = true, dataType = "AuthorizationDTO")
    })
    @PostMapping
    @Transactional
    public ResponseModel<?> create(@RequestBody AuthorizationDTO authorizationDTO) throws TipException {
        //判断用户名密码是否为空
        if (StringUtils.isEmpty(authorizationDTO.getUsername()) || StringUtils.isEmpty(authorizationDTO.getPassword())) {
            throw new TipException(ErrorConstant.ERROR_MSG_USER_INFO_NOT_NULL, ErrorConstant.ERROR_CODE_USER_INFO_NOT_NULL);
        }
        //判断用户名是否已经存在
        if (userService.findByUserName(authorizationDTO.getUsername()) != null) {
            throw new TipException(ErrorConstant.ERROR_MSG_USER_REGISTER_ERROR, ErrorConstant.ERROR_CODE_USER_REGISTER_ERROR);
        }
        //判断账号密码是否大于8位
        if (authorizationDTO.getPassword().length() <= 8) {
            throw new TipException(ErrorConstant.ERROR_MSG_USER_PASSWORD_SHORT_ERROR, ErrorConstant.ERROR_CODE_USER_PASSWORD_SHORT_ERROR);
        }
        //把dto中的属性拷贝给user对象。
        User user = new User();
        BeanUtils.copyProperties(authorizationDTO, user);
        //MD5加密用户密码
        String encryptPassword = DigestUtils.md5DigestAsHex(authorizationDTO.getPassword().getBytes());
        //设置为加密后的密码
        user.setPassword(encryptPassword);
        //保存用户信息
        User savedUser = userService.create(user);
        //创建角色
        Role userRole = new Role();
        //初始化为角色为用户
        userRole.setRole(RoleConstant.ROLE_USER);
        //角色关联到用户
        userRole.setUsers(Collections.singletonList(savedUser));
        //保存角色
        roleService.save(userRole);
        //关注自己（自己发的动态也会添加到自己的动态流中）
        friendService.follow(savedUser.getId(), savedUser.getId());

        UserVO savedUserVo = new UserVO();
        //把用户信息copy到userVO中
        BeanUtils.copyProperties(savedUser, savedUserVo);
        //创建统一的返回模式
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_CREATED).message(HttpStatus.STATUS_INFO_CREATED).data(savedUserVo).build();
    }

    @Authorization(role = RoleConstant.ROLE_ADMIN)
    @ApiOperation(value = "删除用户", notes = "删除用户")
    @ApiImplicitParam(name = "id", required = true, dataType = "Long", paramType = "path")
    @DeleteMapping(value = "{id}")
    public ResponseModel<?> delete(@PathVariable("id") Long id) throws TipException {
        if (userService.findById(id) != null)
            userService.delete(id);
        else
            throw new TipException(ErrorConstant.ERROR_MSG_USER_NOT_FOUND, ErrorConstant.ERROR_CODE_USER_NOT_FOUND);
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_ACCEPTED).message(HttpStatus.STATUS_INFO_ACCEPTED).build();
    }

    @ApiOperation(value = "获取用户的动态", notes = "获取用户的动态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, dataType = "Long", paramType = "path"),
            @ApiImplicitParam(name = "page", value = "页", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "size", value = "单页显示数量", dataType = "Integer", paramType = "query")
    })
    @GetMapping(value = "{id}/feeds")
    public ResponseModel<?> feeds(@PathVariable("id") Long id,
                                  @RequestParam(value = "page", defaultValue = "0") Integer page,
                                  @RequestParam(value = "size", defaultValue = "10") Integer size) throws TipException {
        //查询id是否存在
        if (userService.findById(id) == null) {
            throw new TipException(ErrorConstant.ERROR_MSG_USER_NOT_FOUND, ErrorConstant.ERROR_CODE_USER_NOT_FOUND);
        }
        //
        List<Event> events = feedService.findEventsByAuthorId(id, new PageRequest(page, size, new Sort(Sort.Direction.DESC, "createTime", "id"))).getContent();
        //组装FeedVO
        List<FeedVO> feedVOS = FeedUtils.assemblingFeedVO(events, postService, countService, imageService, commentService);
        return ResponseModel.builder().code(HttpStatus.STATUS_CODE_SUCCESS).message(HttpStatus.STATUS_INFO_SUCCESS).data(feedVOS).build();
    }
}
